/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package unc.pds.model;

import java.rmi.RemoteException;
import java.util.Date;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.jms.MapMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import unc.pds.auth.ISecurityApplyer;
import unc.pds.auth.SecurityST;
import unc.pds.data.Consts;
import unc.pds.exc.PDSSecurityException;
import unc.pds.exc.RDBSecurityException;
import unc.pds.data.RoleMap;
import unc.pds.data.RootDataBeanRemote;
import unc.pds.data.RootDataBeanRemoteHome;
import unc.pds.filemodel.AlbumRemote;
import unc.pds.filemodel.AlbumRemoteHome;
import unc.pds.filemodel.FolderRemote;
import unc.pds.filemodel.FolderRemoteHome;
import unc.pds.news.News;
import unc.pds.news.NewsMessage;
import unc.pds.news.NewsReader;
import unc.pds.util.Arch;
import unc.pds.util.ArchImpl;

/**
 *
 * @author ain
 */
public class User implements SessionBean, Model, IUser, Newsable {

    private static String default_object_type = Consts.OBJECT_TYPE__USER;
    private SessionContext context;
    private Long sessionKey;
    unc.pds.data.RootDataBeanRemote dataBean;

    // <editor-fold defaultstate="collapsed" desc="EJB infrastructure methods. Click the + sign on the left to edit the code.">;
    // TODO Add code to acquire and use other enterprise resources (DataSource, JMS, enterprise bean, Web services)
    // TODO Add business methods or web service operations
    /**
     * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
     */
    public void setSessionContext(SessionContext aContext) {
        context = aContext;
    }

    /**
     * @see javax.ejb.SessionBean#ejbActivate()
     */
    public void ejbActivate() {
    }

    /**
     * @see javax.ejb.SessionBean#ejbPassivate()
     */
    public void ejbPassivate() {
    }

    /**
     * @see javax.ejb.SessionBean#ejbRemove()
     */
    public void ejbRemove() throws RemoteException {
    }

    // </editor-fold>;
    /**
     * See section 7.10.3 of the EJB 2.0 specification
     * See section 7.11.3 of the EJB 2.1 specification
     */
    /*public void ejbCreate() {
    // TODO implement ejbCreate if necessary, acquire resources
    // This method has access to the JNDI context so resource aquisition
    // spanning all methods can be performed here such as home interfaces
    // and data sources.
    }*/
    public void ejbCreate(unc.pds.data.RootDataBeanRemote rdb, Long nsessionKey) throws RemoteException {
        dataBean = rdb;
        sessionKey = nsessionKey;
        dataBean.setSessionKey(sessionKey);
        try {
            if (dataBean.hasField(Consts.ATTR__USER_NOTINITIAL, Consts.ATTR__USER_NOTINITIAL)) {
                onCreate();
            }
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
        }
    }

    public void ejbCreate(String nickname, Long nsessionKey) throws NamingException, RemoteException {
        try {
            Arch doc = new ArchImpl("root", "");
            Arch name = new ArchImpl(Consts.ATTR__USER_NICKNAME, nickname);
            doc.addChild(name);
            RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            dataBean = rdbrh.findByFieldSet(doc, this.default_object_type);

        } catch (Exception e) {
            throw new EJBException(e.getLocalizedMessage());
        }
        sessionKey = nsessionKey;
        dataBean.setSessionKey(sessionKey);
        try {
            if (dataBean.hasField(Consts.ATTR__USER_NOTINITIAL, Consts.ATTR__USER_NOTINITIAL)) {
                onCreate();
            }
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
        }
    }

    /*public void ejbCreate(Arch doc, Long nsessionKey) throws CreateException, RemoteException {
    sessionKey = nsessionKey;
    try {
    if (doc.getChild(Consts.ARCH_F_TYPE) == null) {
    doc.addChild(new ArchImpl(Consts.ARCH_F_TYPE, Consts.OBJECT_TYPE__USER));
    }
    RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
    dataBean = rdbrh.create(doc, sessionKey);
    dataBean.setSessionKey(sessionKey);
    } catch (Exception nex) {
    throw new CreateException("DIARY: CREATEbyDOC: " + nex.getLocalizedMessage());
    }
    }
     */
    private void onCreate() throws RemoteException, PDSSecurityException {
        dataBean.dropParameter(Consts.ATTR__USER_NOTINITIAL, Consts.ATTR__USER_NOTINITIAL);
        SecurityST.getSecurityApplyer(sessionKey).onCreate(getKey());
        try {
            ISecurityApplyer secapp = SecurityST.getSecurityApplyer(sessionKey);
            secapp.onCreate(getKey());
            dataBean.addParameter(Consts.ATTR__USER_MEMBER_OF, secapp.getMarkerGroupId("users").toString());
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
        }

    }

    public Date getDate() throws RemoteException {
        return dataBean.getCrDate();
    }

    public String getNickname() throws RemoteException {
        return dataBean.getParameter(Consts.ATTR__USER_NICKNAME);
    }

    public String getEmail() throws RemoteException {
        return dataBean.getParameter(Consts.ATTR__USER_EMAIL);
    }

    public String getName() throws RemoteException {
        return dataBean.getParameter(Consts.ATTR__USER_NAME);
    }

    public String getSername() throws RemoteException {
        return dataBean.getParameter(Consts.ATTR__USER_SERNAME);
    }

    public DiaryRemote[] getDiares() throws RemoteException {
        try {

            DiaryRemoteHome drh =
                    (DiaryRemoteHome) (new InitialContext()).lookup("ejb/Diary");
            RootDataBeanRemoteHome rdbrh =
                    (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            Collection bean = rdbrh.findByParentKey(this.getKey(), Consts.OBJECT_TYPE__DIARY);

            DiaryRemote[] ans = new DiaryRemote[bean.size()];
            for (int i = 0; i < bean.size(); i++) {
                ((RootDataBeanRemote) (bean.toArray()[i])).setSessionKey(sessionKey);
                ans[i] = drh.create((RootDataBeanRemote) (bean.toArray()[i]), sessionKey);
            }
            return ans;
        } catch (Exception e) {
            throw new RemoteException("USER:GETDIARES: " + e.getLocalizedMessage());
        }
    }

    public void addDiary(Arch doc) throws RemoteException {
        try {
            DiaryRemoteHome drh = (DiaryRemoteHome) (new InitialContext()).lookup("ejb/Diary");
            doc.addChild(new ArchImpl(Consts.ARCH_F_PARENT, dataBean.getPrimaryKey().toString()));
            doc.addChild(new ArchImpl(Consts.ATTR__DIARY_AUTHOR, dataBean.getPrimaryKey().toString()));
            DiaryRemote DR = drh.create(doc, sessionKey);
            if (Consts.DEBUG_MODE) System.out.println("User.addDiary: created ");
            generateNews("create", DR.getKey());
            if (Consts.DEBUG_MODE) System.out.println("User.addDiary: News created");
            //dataBean.addParameter(Consts.ATTR__USER_DIARY, DR.getKey().toString());
        } catch (Exception e) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR:USER:addDiary: " + e.getLocalizedMessage());
            throw new RemoteException("USER:addDiary: " + e.getLocalizedMessage());
        }
    }

    public AlbumRemote[] getAlbums() throws RemoteException {
        try {

            AlbumRemoteHome drh =
                    (AlbumRemoteHome) (new InitialContext()).lookup("ejb/Album");
            RootDataBeanRemoteHome rdbrh =
                    (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            Collection bean = rdbrh.findByParentKey(this.getKey(), Consts.OBJECT_TYPE__ALBUM);

            AlbumRemote[] ans = new AlbumRemote[bean.size()];
            for (int i = 0; i < bean.size(); i++) {
                ((RootDataBeanRemote) (bean.toArray()[i])).setSessionKey(sessionKey);
                ans[i] = drh.create((RootDataBeanRemote) (bean.toArray()[i]), sessionKey);
            }
            return ans;
        } catch (Exception e) {
            throw new RemoteException("USER:GETAlbumS: " + e.getLocalizedMessage());
        }
    }

    public void addAlbum(Arch doc) throws RemoteException {
        try {
            AlbumRemoteHome drh = (AlbumRemoteHome) (new InitialContext()).lookup("ejb/Album");
            doc.addChild(new ArchImpl(Consts.ARCH_F_PARENT, dataBean.getPrimaryKey().toString()));
            doc.addChild(new ArchImpl(Consts.ATTR__ALBUM_AUTHOR, dataBean.getPrimaryKey().toString()));
            AlbumRemote DR = drh.create(doc, sessionKey);
            if (Consts.DEBUG_MODE) System.out.println("User.addAlbum: created ");
            //dataBean.addParameter(Consts.ATTR__USER_DIARY, DR.getKey().toString());
        } catch (Exception e) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR:USER:addAlbum: " + e.getLocalizedMessage());
            throw new RemoteException("USER:addAlbum: " + e.getLocalizedMessage());
        }
    }

    public FolderRemote[] getFolders() throws RemoteException {
        try {

            FolderRemoteHome drh =
                    (FolderRemoteHome) (new InitialContext()).lookup("ejb/Folder");
            RootDataBeanRemoteHome rdbrh =
                    (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            Collection bean = rdbrh.findByParentKey(this.getKey(), Consts.OBJECT_TYPE__FOLDER);

            FolderRemote[] ans = new FolderRemote[bean.size()];
            for (int i = 0; i < bean.size(); i++) {
                ((RootDataBeanRemote) (bean.toArray()[i])).setSessionKey(sessionKey);
                ans[i] = drh.create((RootDataBeanRemote) (bean.toArray()[i]), sessionKey);
            }
            return ans;
        } catch (Exception e) {
            throw new RemoteException("USER:getFolders: " + e.getLocalizedMessage());
        }
    }

    public void addFolder(Arch doc) throws RemoteException {
        try {
            FolderRemoteHome drh = (FolderRemoteHome) (new InitialContext()).lookup("ejb/Folder");
            doc.addChild(new ArchImpl(Consts.ARCH_F_PARENT, dataBean.getPrimaryKey().toString()));
            doc.addChild(new ArchImpl(Consts.ATTR__FOLDER_AUTHOR, dataBean.getPrimaryKey().toString()));
            FolderRemote DR = drh.create(doc, sessionKey);
            if (Consts.DEBUG_MODE) System.out.println("User.addFolder: created ");
        } catch (Exception e) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR:USER:addAlbum: " + e.getLocalizedMessage());
            throw new RemoteException("USER:addAlbum: " + e.getLocalizedMessage());
        }
    }

    public void createGroup(Arch doc) throws RemoteException {
        try {
            GroupRemoteHome drh = (GroupRemoteHome) (new InitialContext()).lookup("ejb/Group");
            doc.addChild(new ArchImpl(Consts.ARCH_F_PARENT, dataBean.getPrimaryKey().toString()));
            //doc.addChild(new ArchImpl(Consts.ATTR__FOLDER_AUTHOR, dataBean.getPrimaryKey().toString()));
            GroupRemote DR = drh.create(doc, sessionKey);
            SecurityST.getSecurityApplyer(sessionKey).onCreate(DR.getKey());
            if (Consts.DEBUG_MODE) System.out.println("User.CreateGroup: created ");
        } catch (Exception e) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR:User.CreateGroup: " + e.getLocalizedMessage());
            throw new RemoteException("User.CreateGroup: " + e.getLocalizedMessage());
        }
    }

    public GroupRemote[] getGroups() throws RemoteException {
        try {
            Collection modelBeans = ModelFactory.getByParentKey(this.getKey(), Consts.OBJECT_TYPE__GROUP, sessionKey);
            String[] keys = dataBean.getParameters(Consts.ATTR__USER_MEMBER_OF);
            for (int i = 0; i < keys.length; i++) {
                try {
                    Model temp = ModelFactory.getByKey(new Long(Long.parseLong(keys[i])), Consts.OBJECT_TYPE__GROUP, sessionKey);
                    modelBeans.add(temp);
                } catch (Exception e) {
                }
            }
            GroupRemote[] ans = new GroupRemote[modelBeans.size()];
            return (GroupRemote[]) modelBeans.toArray(ans);
        } catch (Exception e) {
            throw new RemoteException("USER:getGroups: " + e.getLocalizedMessage());
        }
    }

    public GroupRemote[] getMarkerGroups() throws RemoteException {
        try {
            Collection modelBeans = new ArrayList();
            String[] keys = dataBean.getParameters(Consts.ATTR__USER_MEMBER_OF);
            for (int i = 0; i < keys.length; i++) {
                try {
                    Model temp = ModelFactory.getByKey(new Long(Long.parseLong(keys[i])), Consts.OBJECT_TYPE__MARGROUP, sessionKey);
                    modelBeans.add(temp);
                } catch (Exception e) {
                }
            }
            GroupRemote[] ans = new GroupRemote[modelBeans.size()];
            return (GroupRemote[]) modelBeans.toArray(ans);
        } catch (Exception e) {
            throw new RemoteException("USER:getGroups: " + e.getLocalizedMessage());
        }
    }

    private void generateNews(String event, Long eventID) throws RemoteException {
        try {
            QueueConnectionFactory connfac = (QueueConnectionFactory) (new InitialContext()).lookup("jms/newsQueueConnection");
            QueueConnection conn = connfac.createQueueConnection();
            QueueSession sess = conn.createQueueSession(true, QueueSession.AUTO_ACKNOWLEDGE);

            Queue queue = (Queue) (new InitialContext()).lookup("jms/newsQueue");
            QueueSender sender = sess.createSender(queue);
            if (Consts.DEBUG_MODE) System.out.println("sender created");
            NewsMessage m = new NewsMessage();
            m.setLongProperty(NewsMessage.CONTEXT_ID_KEY, getKey().longValue());
            m.setStringProperty(NewsMessage.EVENT_NAME_KEY, event);
            m.setLongProperty(NewsMessage.ENTITY_ID_KEY, eventID.longValue());
            if (Consts.DEBUG_MODE) System.out.println("Filled message");
            sender.send(m);
            if (Consts.DEBUG_MODE) System.out.println("message sended");
            sender.close();
            sess.close();
            conn.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RemoteException("getNews: " + ex.toString());
        }
    }

    public ArrayList getNews() throws RemoteException {
        ArrayList answer = new ArrayList();
        UserRemote[] friends = getFriends();
        for (int i = 0; i < friends.length; i++) {
            answer.addAll((new NewsReader()).getNewsFor(friends[i].getKey()));
        }
        GroupRemote[] groups = getGroups();
        for (int i = 0; i < groups.length; i++) {
            answer.addAll((new NewsReader()).getNewsFor(groups[i].getKey()));
        }
        News[] news = (News[]) answer.toArray(new News[answer.size()]);
        Arrays.sort(news);
        answer = new ArrayList();
        answer.addAll(Arrays.asList(news));
        return answer;
    }

    public Long getKey() throws RemoteException {
        return (Long) dataBean.getPrimaryKey();
    }

    public Model getParent() throws RemoteException {
        return null;
    }

    public void wasInvitedByUser(Long key) throws RemoteException {
        dataBean.addParameter(Consts.ATTR__USER_NEWFRIEND, key.toString());
    }

    public void sendInviteToUser(Long key) throws RemoteException {
        UserRemote ur = (UserRemote) ModelFactory.getByKey(key, sessionKey);
        ur.wasInvitedByUser(dataBean.getID());
        dataBean.addParameter(Consts.ATTR__USER_WANNEDFRIEND, key.toString());
    }

    public void acceptUserInvite(Long key) throws RemoteException {
        dataBean.addParameter(Consts.ATTR__USER_FRIEND, key.toString());
        dataBean.dropParameter(Consts.ATTR__USER_NEWFRIEND, key.toString());
        ((UserRemote) ModelFactory.getByKey(key, sessionKey)).wasAcceptedByUser(getKey());
        try {
            SecurityST.getSecurityApplyer(sessionKey).onNewFriend(getKey(), key);
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
            throw new RemoteException(ex.getLocalizedMessage());
        }
    }

    public void wasAcceptedByUser(Long key) throws RemoteException {
        dataBean.addParameter(Consts.ATTR__USER_FRIEND, key.toString());
        dataBean.dropParameter(Consts.ATTR__USER_WANNEDFRIEND, key.toString());
        try {
            SecurityST.getSecurityApplyer(sessionKey).onNewFriend(getKey(), key);
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
            throw new RemoteException(ex.getLocalizedMessage());
        }
    }

    public void delcineUserInvite(Long key) throws RemoteException {
        dataBean.dropParameter(Consts.ATTR__USER_NEWFRIEND, key.toString());
        ((UserRemote) ModelFactory.getByKey(key, sessionKey)).wasDeclinedByUser(getKey());
    }

    public void wasDeclinedByUser(Long key) throws RemoteException {
        dataBean.dropParameter(Consts.ATTR__USER_WANNEDFRIEND, key.toString());
    }

    public void wasInvitedByGroup(Long key) throws RemoteException {
        dataBean.addParameter(Consts.ATTR__USER_NEWGROUP, key.toString());
    }

    public void sendInviteToGroup(Long key) throws RemoteException {
        GroupRemote ur = (GroupRemote) ModelFactory.getByKey(key, sessionKey);
        ur.wasInvitedByUser(dataBean.getID());
        dataBean.addParameter(Consts.ATTR__USER_WANTEDGROUP, key.toString());
    }

    public void acceptGroupInvite(Long key) throws RemoteException {
        dataBean.addParameter(Consts.ATTR__USER_MEMBER_OF, key.toString());
        dataBean.dropParameter(Consts.ATTR__USER_NEWGROUP, key.toString());
        ((GroupRemote) ModelFactory.getByKey(key, sessionKey)).wasAcceptedByUser(getKey());
    }

    public void wasAcceptedByGroup(Long key) throws RemoteException {
        dataBean.addParameter(Consts.ATTR__USER_MEMBER_OF, key.toString());
        dataBean.dropParameter(Consts.ATTR__USER_WANTEDGROUP, key.toString());
    }

    public void delcineGroupInvite(Long key) throws RemoteException {
        dataBean.dropParameter(Consts.ATTR__USER_NEWGROUP, key.toString());
        ((GroupRemote) ModelFactory.getByKey(key, sessionKey)).wasDeclinedByUser(getKey());
    }

    public void wasDeclinedByGroup(Long key) throws RemoteException {
        dataBean.dropParameter(Consts.ATTR__USER_WANTEDGROUP, key.toString());
    }

    public void removeGroup(Long key) throws RemoteException {
        ((GroupRemote) ModelFactory.getByKey(key, sessionKey)).wasRemovedFromGroupsBy(getKey());
        dataBean.dropParameter(Consts.ATTR__USER_MEMBER_OF, key.toString());
    }

    public void wasRemovedFromGroupBy(Long key) throws RemoteException {
        dataBean.dropParameter(Consts.ATTR__USER_MEMBER_OF, key.toString());
    }

    public void removeFriend(Long key) throws RemoteException {
        dataBean.dropParameter(Consts.ATTR__USER_FRIEND, key.toString());
        ((UserRemote) ModelFactory.getByKey(key, sessionKey)).wasRemovedFromFriendsBy(getKey());
        try {
            SecurityST.getSecurityApplyer(sessionKey).onDelFriend(getKey(), key);
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
            throw new RemoteException(ex.getLocalizedMessage());
        }
    }

    public void wasRemovedFromFriendsBy(Long key) throws RemoteException {
        dataBean.dropParameter(Consts.ATTR__USER_FRIEND, key.toString());
        try {
            SecurityST.getSecurityApplyer(sessionKey).onDelFriend(getKey(), key);
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
            throw new RemoteException(ex.getLocalizedMessage());
        }
    }

    public void banFriend(Long key) throws RemoteException {
        dataBean.dropParameter(Consts.ATTR__USER_FRIEND, key.toString());
        dataBean.addParameter(Consts.ATTR__USER_BANFRIEND, key.toString());
        try {
            SecurityST.getSecurityApplyer(sessionKey).onBanFriend(getKey(), key);
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
            throw new RemoteException(ex.getLocalizedMessage());
        }
    }

    public void unbanFriend(Long key) throws RemoteException {
        dataBean.addParameter(Consts.ATTR__USER_FRIEND, key.toString());
        dataBean.dropParameter(Consts.ATTR__USER_BANFRIEND, key.toString());
        try {
            SecurityST.getSecurityApplyer(sessionKey).onUnBanFriend(getKey(), key);
        } catch (PDSSecurityException ex) {
            ex.printStackTrace();
            throw new RemoteException(ex.getLocalizedMessage());
        }
    }

    public UserRemote[] getFriends() throws RemoteException {
        try {
            String[] keys = dataBean.getParameters(Consts.ATTR__USER_FRIEND);
            UserRemote[] ans = new UserRemote[keys.length];
            for (int i = 0; i < ans.length; i++) {
                ans[i] = (UserRemote) ModelFactory.getByKey(new Long(Long.parseLong(keys[i])), sessionKey);
            }
            return ans;
        } catch (Exception e) {
            throw new RemoteException("USER:GETAlbumS: " + e.getLocalizedMessage());
        }
    }

    public UserRemote[] getNewFriends() throws RemoteException {
        try {
            String[] keys = dataBean.getParameters(Consts.ATTR__USER_NEWFRIEND);
            UserRemote[] ans = new UserRemote[keys.length];
            for (int i = 0; i < ans.length; i++) {
                ans[i] = (UserRemote) ModelFactory.getByKey(new Long(Long.parseLong(keys[i])), sessionKey);
            }
            return ans;
        } catch (Exception e) {
            throw new RemoteException("USER:GETAlbumS: " + e.getLocalizedMessage());
        }
    }

    public UserRemote[] getBanFriends() throws RemoteException {
        try {
            String[] keys = dataBean.getParameters(Consts.ATTR__USER_BANFRIEND);
            UserRemote[] ans = new UserRemote[keys.length];
            for (int i = 0; i < ans.length; i++) {
                ans[i] = (UserRemote) ModelFactory.getByKey(new Long(Long.parseLong(keys[i])), sessionKey);
            }
            return ans;
        } catch (Exception e) {
            throw new RemoteException("USER:GETAlbumS: " + e.getLocalizedMessage());
        }
    }

    public void dropMe() throws RemoteException {
        try {
            dataBean.dropMe();
        } catch (Exception e) {
            throw new RemoteException(e.getLocalizedMessage());
        }
    }

    public List getRolesForUser(Long key) throws RemoteException {
        List ans = new ArrayList();
        boolean flag = false;
        if (getKey().compareTo(key) == 0) {
            flag = true;
            Arch doc = new ArchImpl("root", null);
            doc.addChild(new ArchImpl(Consts.ATTR__ROLE_NAME, Consts.ROLE_OWNER));
            try {
                RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
                RootDataBeanRemote rdbr = rdbrh.findByFieldSet(doc, Consts.OBJECT_TYPE__ROLE);
                rdbr.setSessionKey(sessionKey);
                if (Consts.DEBUG_MODE) System.out.println("        get RDB");
                RoleRemoteHome rrh = (RoleRemoteHome) (new InitialContext()).lookup("ejb/Role");
                RoleRemote rr = rrh.create(rdbr, sessionKey);
                if (Consts.DEBUG_MODE) System.out.println("        cast RoleRemote");
                rr.setLevel(Consts.ROLE_LEVEL_USER);
                ans.add(rr);
            } catch (Exception e) {
                if (Consts.DEBUG_MODE) System.out.println("ERROR: User.getRoles: " + e.getLocalizedMessage());
                throw new RemoteException("User.getRoleForUser: " + e.getLocalizedMessage());
            }
        }
        if (dataBean.isFriend(key)) {
            flag = true;
            Arch doc = new ArchImpl("root", null);
            doc.addChild(new ArchImpl(Consts.ATTR__ROLE_NAME, Consts.ROLE_FRIEND));
            try {
                RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
                RootDataBeanRemote rdbr = rdbrh.findByFieldSet(doc, Consts.OBJECT_TYPE__ROLE);
                rdbr.setSessionKey(sessionKey);
                if (Consts.DEBUG_MODE) System.out.println("        get RDB");
                RoleRemoteHome rrh = (RoleRemoteHome) (new InitialContext()).lookup("ejb/Role");
                RoleRemote rr = rrh.create(rdbr, sessionKey);
                if (Consts.DEBUG_MODE) System.out.println("        cast RoleRemote");
                rr.setLevel(Consts.ROLE_LEVEL_USER);
                ans.add(rr);
            } catch (Exception e) {
                if (Consts.DEBUG_MODE) System.out.println("ERROR: User.getRoles: " + e.getLocalizedMessage());
                throw new RemoteException("User.getRoleForUser: " + e.getLocalizedMessage());
            }
        }
        if (dataBean.isWannedFriend(key)) {
            flag = true;
            Arch doc = new ArchImpl("root", null);
            doc.addChild(new ArchImpl(Consts.ATTR__ROLE_NAME, Consts.ROLE_WANNEDFRIEND));
            try {
                RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
                RootDataBeanRemote rdbr = rdbrh.findByFieldSet(doc, Consts.OBJECT_TYPE__ROLE);
                rdbr.setSessionKey(sessionKey);
                if (Consts.DEBUG_MODE) System.out.println("        get RDB");
                RoleRemoteHome rrh = (RoleRemoteHome) (new InitialContext()).lookup("ejb/Role");
                RoleRemote rr = rrh.create(rdbr, sessionKey);
                if (Consts.DEBUG_MODE) System.out.println("        cast RoleRemote");
                rr.setLevel(Consts.ROLE_LEVEL_USER);
                ans.add(rr);
            } catch (Exception e) {
                if (Consts.DEBUG_MODE) System.out.println("ERROR: User.getRoles: " + e.getLocalizedMessage());
                throw new RemoteException("User.getRoleForUser: " + e.getLocalizedMessage());
            }
        }
        if (dataBean.isEnemy(key)) {
            flag = true;
            Arch doc = new ArchImpl("root", null);
            doc.addChild(new ArchImpl(Consts.ATTR__ROLE_NAME, Consts.ROLE_BANNED));
            try {
                RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
                RootDataBeanRemote rdbr = rdbrh.findByFieldSet(doc, Consts.OBJECT_TYPE__ROLE);
                rdbr.setSessionKey(sessionKey);
                if (Consts.DEBUG_MODE) System.out.println("        get RDB");
                RoleRemoteHome rrh = (RoleRemoteHome) (new InitialContext()).lookup("ejb/Role");
                RoleRemote rr = rrh.create(rdbr, sessionKey);
                if (Consts.DEBUG_MODE) System.out.println("        cast RoleRemote");
                rr.setLevel(Consts.ROLE_LEVEL_USER);
                ans.add(rr);
            } catch (Exception e) {
                if (Consts.DEBUG_MODE) System.out.println("ERROR: User.getRoles: " + e.getLocalizedMessage());
                throw new RemoteException("User.getRoleForUser: " + e.getLocalizedMessage());
            }
        }
        if (flag) {
            return ans;
        } else {
            if (Consts.DEBUG_MODE) System.out.println("User.getRole: not any role for " + key);
            return null;
        }
    }

    public String getType() throws RemoteException {
        return default_object_type;
    }

    public boolean isFriend(Long key) throws RemoteException {
        return dataBean.hasField(Consts.ATTR__USER_FRIEND, key.toString());
    }

    public boolean isWannedFriend(Long key) throws RemoteException {
        return dataBean.hasField(Consts.ATTR__USER_WANNEDFRIEND, key.toString());
    }

    public boolean isBanned(Long key) throws RemoteException {
        return dataBean.hasField(Consts.ATTR__USER_BANFRIEND, key.toString());
    }

    public boolean isInGroup(Long key) throws RemoteException {
        return dataBean.hasField(Consts.ATTR__USER_MEMBER_OF, key.toString());
    }
}
